#include "bsp_touch.h"
#include "bsp_system_clock.h"
#include "SEGGER_RTT.h"

/*******************************************************************************
* 函数功能 : 延时函数
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_delay(void){
	delay_us(2);
}
/*******************************************************************************
* 函数功能 : 延时函数
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_delay_ms(void){
	delay_ms(5);
}
/*******************************************************************************
* 函数功能 : 拉低sck时钟线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sck_l(void){
	gpio_bit_reset(GPIOB,GPIO_PIN_13);
}
/*******************************************************************************
* 函数功能 : 拉高sck时钟线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sck_h(void){
	gpio_bit_set(GPIOB,GPIO_PIN_13);
}
/*******************************************************************************
* 函数功能 : 拉低sda数据线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sda_l(void){
	gpio_bit_reset(GPIOB,GPIO_PIN_15);
}
/*******************************************************************************
* 函数功能 : 拉高sda数据线
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sda_h(void){
	gpio_bit_set(GPIOB,GPIO_PIN_15);
}
/*******************************************************************************
* 函数功能 : 设置sda为输出
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sda_out(void){
	;
}
/*******************************************************************************
* 函数功能 : 设置sda为输入
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static void gt911_sda_in(void){
	;
}
/*******************************************************************************
* 函数功能 : 读取sda数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
static uint8_t gt911_sda_read(void){
	return gpio_input_bit_get(GPIOB,GPIO_PIN_15);
}
/*******************************************************************************
* 函数功能 : 读取一个字节数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
uint8_t gt911_read_byte(soft_iic_dev_t *dev, uint16_t readAddr){
	uint8_t ch = 0;
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,readAddr>>8);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,readAddr&0xFF);
	soft_iic_wait_ack(dev);
	
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr+1);
	soft_iic_wait_ack(dev);
	ch = soft_iic_read_byte(dev, 0);
	soft_iic_stop(dev);
	return ch;
}
/*******************************************************************************
* 函数功能 : 读取多个字节数据
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void gt911_read_buf(soft_iic_dev_t *dev, uint16_t readAddr, uint8_t *buf, uint16_t len){
	for(int i=0;i<len;i++){
		buf[i] = gt911_read_byte(dev,readAddr);
		readAddr += 1;
	}
}
/*******************************************************************************
* 函数功能 : 写入单个字节
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void gt911_write_byte(soft_iic_dev_t *dev, uint16_t writeAddr, uint8_t ch){
	soft_iic_start(dev);
	soft_iic_send_byte(dev,dev->slave_addr);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,writeAddr>>8);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,writeAddr&0xFF);
	soft_iic_wait_ack(dev);
	soft_iic_send_byte(dev,ch);
	soft_iic_wait_ack(dev);
	soft_iic_stop(dev);
	dev->delay();
}
/*******************************************************************************
* 函数功能 : 写入多个字节
* 输    入 : 无
* 输    出 : 无
*******************************************************************************/
void gt911_write_buf(soft_iic_dev_t *dev, uint16_t writeAddr, uint8_t *buf, uint16_t len){
	for(int i=0;i<len;i++){
		gt911_write_byte(dev,writeAddr,buf[i]);
		writeAddr += 1;
	}
}
/***************************************************************************************************************************/
soft_iic_dev_t gt911_dev = {
	.delay = gt911_delay,
	.name = "gt911_lcd_touch",
	.reg_addr = 0x00,
	.SCK_L = gt911_sck_l,
	.SCK_H = gt911_sck_h,
	.SDA_L = gt911_sda_l,
	.SDA_H = gt911_sda_h,
	.SDA_IN = gt911_sda_in,
	.SDA_OUT = gt911_sda_out,
	.SDA_READ = gt911_sda_read,
	.delay_ms = gt911_delay_ms,
	.slave_addr = 0x28,
};


static void bsp_touch_gpio_config(void){
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOD);
	
	//sck
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
	
	//sda
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_15);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
	
	//int/irq(先设置为输出模式)
	gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_11);
//  gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	
	//rst
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_12);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
	
	//根据上电时序开始配置触摸芯片的ID
//	gpio_bit_reset(GPIOD,GPIO_PIN_11);
	gpio_bit_reset(GPIOB,GPIO_PIN_12);
	gt911_dev.delay_ms();
	delay_ms(100);
	gpio_bit_set(GPIOB,GPIO_PIN_12);
	gt911_dev.delay_ms();
	gt911_dev.delay_ms();
	delay_ms(100);
	//设置INT为浮空输入状态
	gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_11);
//  gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
	gt911_dev.delay_ms();
	delay_ms(100);
}
uint8_t gt911_id[4] = {0};
uint16_t id_reg_addr = 0x8140;
void bsp_touch_init(void){
	bsp_touch_gpio_config();
	gt911_read_buf(&gt911_dev,id_reg_addr,gt911_id,sizeof(gt911_id));
	SEGGER_RTT_printf(0,"GT911_ID = %c%c%c\r\n",gt911_id[0],gt911_id[1],gt911_id[2]);
	delay_ms(100);
}
gt911_reg_addr_t gt911_reg_addr = {
	.touch_status = 0x814E,
	.point1 = 0X8150,
	.point2 = 0X8158,
	.point3 = 0X8160,
	.point4 = 0X8168,
	.point5 = 0X8170,
};
gt911_touch_data_t gt911_touch_data = {0};
uint8_t point_buf[41] = {0};
void bsp_touch_scan(void){
		gt911_read_buf(&gt911_dev,gt911_reg_addr.touch_status,(uint8_t *)&gt911_touch_data.touch_status ,41);
		if(gt911_touch_data.touch_status.bf.buffer_status != 0 && gt911_touch_data.touch_status.bf.number_point <= 5){
			SEGGER_RTT_printf(0,"%8d %8d - %8d %8d - %8d %8d - %8d %8d - %8d %8d\r\n",gt911_touch_data.point1.x.value,gt911_touch_data.point1.y.value, \
																																								gt911_touch_data.point2.x.value,gt911_touch_data.point2.y.value, \
																																								gt911_touch_data.point3.x.value,gt911_touch_data.point3.y.value, \
																																								gt911_touch_data.point4.x.value,gt911_touch_data.point4.y.value, \
																																								gt911_touch_data.point5.x.value,gt911_touch_data.point5.y.value);
			bsp_touch_status_clean();
		}
}
bool bsp_touch_ok(void){
	gt911_read_buf(&gt911_dev,gt911_reg_addr.touch_status,(uint8_t *)&gt911_touch_data.touch_status ,41);
	if(gt911_touch_data.touch_status.bf.buffer_status != 0 && gt911_touch_data.touch_status.bf.number_point <= 5){
		return true;
	}
	return false;
}
void bsp_touch_get_xy(uint32_t *x, uint32_t *y){
	*x = gt911_touch_data.point1.x.value;
	*y = gt911_touch_data.point1.y.value;
	bsp_touch_status_clean();
}

void bsp_touch_status_clean(void){
	uint8_t value = 0;
	uint16_t reg = 0x814E;
	gt911_write_buf(&gt911_dev,reg,&value,1);
}